<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Dexcalibur - Probe manager</title>

    <!-- styles -->
    <!--## pages/inc/tpl_css.html ##-->


    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>

<body class="dxc-dark">

   
        <!-- Navigation -->
        <!--## pages/inc/menu.html ##-->

        <div id="page-wrapper" class="dxc-dark">
            <div class="row dxc-dark-row">
                <div class="col-lg-8">
                    <h1 class="page-header">Hook manager</h1>
                </div>
                <!--<div class="col-lg-4" style="padding-top:20px">
                    <button type="button" class="btn btn-danger" id="disable-all">Disable all</button>
                    <button type="button" class="btn btn-success" id="enable-all">Enable all</button>                
                    <button type="button" class="btn btn-primary" id="dl-fridascript"><span class="fa fa-download">&nbsp;</span>Download as Frida script</button>
                </div>-->
                <!-- /.col-lg-12 -->
            </div>

            <div class="row justify-content-center"><div class="col-lg-6" id="alertcontainer"></div></div>


            <div class="row dxc-dark-row">
                    <ul class="nav col-lg-12 dxc-second-nav">
                        <li class="nav-item">
                            <a class="nav-link" id="disable-all"><span class="fa fa-toggle-off">&nbsp;</span>Disable all</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" id="enable-all"><span class="fa fa-toggle-on">&nbsp;</span>Enable all</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" id="dl-fridascript"><span class="fa fa-download">&nbsp;</span>Download script</a>
                        </li>
                        <!--
                        <li class="nav-item">
                            <a class="nav-link" href="#"><span class="fa fa-wrench">&nbsp;</span>Dry-run</a>
                        </li>
                    -->
                        <li class="nav-item border border-info dxc-run-btn">
                            <a class="nav-link start-hook" fridaStartType="spawn-self" id="start-hook" href="#"><span class="fa fa-bolt">&nbsp;</span>Run (spawn)</a>
                        </li>
                        <li class="nav-item dxc-orange-btn">
                            <a class="nav-link start-hook" fridaStartType="attach-app-self" id="attachtoapp-hook" href="#"><span class="fa fa-bolt">&nbsp;</span>Attach to app</a>
                        </li>
                        <li class="nav-item dxc-purple-btn">
                            <a class="nav-link start-hook" fridaStartType="attach-gadget" id="attachtogadget-hook" href="#"><span class="fa fa-bolt">&nbsp;</span>Attach to Gadget</a>
                        </li>

                        <li class="nav-item dxc-red-btn">
                            <a class="nav-link start-server" id="startServer" href="#">
                                Frida server :&nbsp;<span class="badge badge-pill badge-danger" style="font-size:0.8em" id="statusServer">stopped (click to start)</span>
                            </a>
                        </li>
                        <!--<li class="nav-item dxc-purple-btn">
                            <a class="nav-link start-hook" fridaStartType="attach-pid" id="attachto-hook"><span class="fa fa-bolt">&nbsp;</span>Attach to ...</a>
                        </li>-->
                    </ul>
                </div>

            <!-- /.row -->
            <div class="row dxc-dark-row">
                <div class="col-lg-12">
                        
                    <table width="100%" class="table table-striped table-bordered table-hover" id="dataTables-probe">
                        <thead>
                            <tr>
                                <th></th>
                                <th>Type</th>
                                <th>Method</th>
                                <th>Status</th>
                                <th>Action</th>
                            </tr>
                        </thead>
                        <tbody>
                            
                        </tbody>
                    </table>
                    <!-- /.table-responsive -->
                
                   
                </div>
                <!-- /.col-lg-12 -->
            </div>

        </div>
        <!-- /#page-wrapper -->
    
    <div class="modal fade" id="methodModal" tabindex="-1" role="dialog" aria-labelledby="methodModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-lg" role="document">
          <div class="modal-content">
            <div class="modal-header">
              <h3 class="modal-title" id="methodModalLabel">Method details</h3>
              <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
            <div class="modal-body">
              &nbsp;
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
            </div>
          </div>
        </div>
      </div>

      <!--<div class="modal fade" id="fridaConsoleModal" tabindex="-1" role="dialog" aria-labelledby="fridaConsoleLabel" aria-hidden="true">
        <div class="modal-dialog modal-lg" role="document">
          <div class="modal-content">
            <div class="modal-header">
              <h3 class="modal-title" id="fridaConsoleLabel">Frida console</h3>
              <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
            <div class="modal-body">
            
              <div class="input-group">
                    <span class="input-group-prepend">
                         Remote script
                    </span>
                    <input type="text" class="form-control" placeholder='http://...' id="frida_script_url">
                    <span class="input-group-append">
                        <button class="btn btn-primary" id="button_search" type="button">
                            <span class="fa fa-search">&nbsp;</span>
                            Load
                        </button>
                    </span>
              </div>
              <div class="dxc-editor"></div>
              <div class="dxc-output"></div>

            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
            </div>
          </div>
        </div>
      </div>-->

      <div class="modal fade" id="attachToModal" tabindex="-1" role="dialog" aria-labelledby="attachToModalLabel" aria-hidden="true">
        <div class="modal-dialog"  role="document">
          <div class="modal-content" style="width:40pc"  >
            <div class="modal-header">
              <h3 class="modal-title" id="attachToModalLabel">Attach to ...</h3>
            </div>
            <div class="modal-body">
                <div class="row" style="margin-bottom: 1em">
                    <div class="col-lg-8">Select a device:</div>
                    <div class="col-lg-4" >
                        <span class="badge badge-secondary badge-pill badge-sm">-</span>
                    </div>
                </div>
                <div class="row" style="margin-bottom: 1em">
                    <div class="col-lg-12">
                        <select id="ps-device-list"class="form-control"></select>
                    </div>
                </div>
                <div class="row">
                    <div class="col-lg-12 dxc-horizon-separator">
                        <table class="table table-bordered table-hover">
                            <thead>
                                <tr>
                                    <th class="col-md-1">-</th>
                                    <th class="col-md-1">PID</th>
                                    <th class="col-md-4">User</th>
                                    <th class="col-md-6">Process</th>
                                </tr>
                            </thead>
                        </table>
                    </div>
                </div>
            
           
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">
                <span class="fa fa-close"></span>&nbsp;Cancel</button>
              <button type="button" class="btn btn-success btn-sm" data-dismiss="modal">
                  <span class="fa fa-bolt"></span>&nbsp;Attach</button>
            </div>
          </div>
        </div>
      </div>

    <!--## pages/inc/tpl_js_end.html ##-->
    <!--## pages/inc/tpl_ace_js.html ##-->

    <script>

    function setupAceEditor(id){
        var editor = ace.edit(id);
        editor.setTheme("ace/theme/monokai"); //
    
        editor.setOptions({
            maxLines: 50, 
            fontSize: "12pt"
        });
        //editor.setUseWorker(false);
        editor.session.setMode("ace/mode/javascript");
        return editor;
    }
    //    setupAceEditor();
    var IdRegister = new Wexcalibur();
    // keep a record of the instanciated editor for each Id
    var EditorRegister = {};
     

    function saveEditor(id,editor){
        EditorRegister[id]=editor;
    }
    function htmlEncode(txt){
        return $("<div />").text(txt).html();
    }


    function renderMethodModal( row ) {
        let body = '', j=0;


        //body += '<table class="table table-sm"><thead><tr><th scope="col">Role</th><th scope="col">Action</th><th scope="col">Type</th><th scope="col">Name</th></thead><tbody>';
        body += '<table class="table table-sm">';
        body += '<tr><td><b>Modifiers</b></td><td>';

        for(let i in row.modifiers){
            if(j==8) body+="<br>";
            if(row.modifiers[i]==true){
                body += '&nbsp;<span class="badge badge-pill badge-success">'+htmlEncode(i)+'</span>';
            }else{
                body += '&nbsp;<span class="badge badge-pill badge-secondary">'+htmlEncode(i)+'</span>';
            }
            j++;
        }

        body += '</td></tr>'; 
        body += '<tr><td>Class</td><td><a href="/pages/finder.html?class='+btoa(encodeURIComponent(row.enclosingClass))+'"><span class="fa fa-eye"></span>&nbsp;'+htmlEncode(row.enclosingClass)+'</a></td></tr>';
        body += '<tr><td>Fullname</td><td><a href="/pages/finder.html?method='+btoa(encodeURIComponent(row.__signature__))+'"><span class="fa fa-eye"></span>&nbsp;'+htmlEncode(row.__signature__)+'</a></td></tr>';
        
        for(let i=0;  i<row.args.length; i++){
            sgt = row.args[i].name;
            console.log(row.args[i]);
            body += '<tr><td>Arg '+i+'</td><td><a class="arglink" clsid="'+btoa(encodeURIComponent(sgt))+'">'+htmlEncode(sgt)+'</a></td></tr>';
        }

        body += '<tr><td>Return</td><td><a class="retlink" clsid="'+row.ret.name+'">'+htmlEncode(row.ret.name)+'</td></tr>';
        body += '</table>';

        let codeID = IdRegister.codeReg.next()

        //body += '<h4>Disassembled bytecode</h4>';
        

        body += '<div id="'+codeID+'"></div>';
        $.ajax(
            "../api/method/disass/"+encodeURIComponent(btoa(encodeURIComponent(row.__signature__))),
            {
                method: "get",
                statusCode: {
                    200: function(data){
                        data = JSON.parse(data);
                        let code = $("#"+codeID);
                        //let code = $("#editor1");
                        let codeBody = "";
                        console.log(data,code);
                        for(let i=0; i<data.disass.length; i++){
                            codeBody += "\n";
                            if(data.disass[i].tag!=null){
                                codeBody += "."+data.disass[i].tag.substr(1)+"\n";
                            }
                            if(data.disass[i].instr.length>0){
                                //console.log(data.disass[i].instr);
                                for(let j=0; j<data.disass[i].instr.length; j++){
                                    if(data.disass[i].instr[j].value.indexOf("move-result-object")==0)
                                        codeBody += "\t"+data.disass[i].instr[j].value+"\n";
                                    else    
                                        codeBody += data.disass[i].instr[j].value+"\n";
                                }   
                            }
                        }
                        code.html(codeBody);
                        //code.html("var a=new String('test');");
                        setupAceEditor(codeID);
                    }
                }
            }
        );

        $("#methodModal div.modal-body").html(body);
        return body;
    }

    /* Formatting function for row details - modify as you need */
    function format ( row ) {
        // `d` is the original data object for the row
        let body = '<div class="card">';

 //       body += '<table class="table"><thead><tr><th scope="col">Action</th><th scope="col">Type</th></thead><tbody>';
        body += '<div class="row dxc-hook-ppt"><div class="col-lg-2">Hook UUID</div><div class="col-lg-8">'+htmlEncode(row.id)+'</div></div>';
        body += '<div class="row dxc-hook-ppt"><div class="col-lg-2">Hooked method</div><div class="col-lg-8"><a href="#" methid="'+btoa(encodeURIComponent(row.name))+'" class="showMethod"><span class="fa fa-eye"></span>&nbsp;'+htmlEncode(row.name)+'</a></div></div>';
        body += '<div class="row dxc-hook-ppt"><div class="col-lg-2">Description</div><div class="col-lg-8">'+((row.description!=null)?htmlEncode(row.description):'<i>empty</i>')+'</div></div>';
        body += "</div>";

        //body += '<tr><td><b>Intercept</b></td><td>[None]</td></tr>';

        let codeID = IdRegister.codeReg.next();

        body += '</table>';
        //body += '<h4>Hook code</h4><pre id="'+codeID+'">'+decodeURIComponent(atob(row.script))+'</pre>';
        //body += '<h4>Hook code</h4>';
        body += `<div class="row">
                    <div class="col-lg-8">
                        <div class="card">
                            <div class="card-header">
                                <div class="row">
                                    <div class="col-lg-10" style="font-size:1.2em">  
                                        Hook code
                                    </div>
                                    <div class="col-lg-2" style="text-align:right">
                                        <div code="`+codeID+`" hookid="`+row.id+`" class="btn btn-danger savechange" hookreplay="auto" data-toggle="tooltip" data-placement="bottom" title="Save & replay" style="font-size:0.8em"><span class="fa fa-refresh bold"></span>&nbsp;<span class="fa fa-save"></span></div>
                                        <div code="`+codeID+`" hookid="`+row.id+`" class="btn btn-danger savechange" hookreplay="none" data-toggle="tooltip" data-placement="bottom" title="Save change" style="font-size:0.8em"><span class="fa fa-save"></span>&nbsp;</div>
                                    </div>
                                </div>
                            </div>
                            <div class="card-body" style="padding:0px;">
                                    <ul class="nav">
                                        <li class="nav-item">
                                            <span class="nav-link">Helpers:</span>
                                        </li>

                                        <li class="nav-item dropdown">
                                            <a class="nav-link dropdown-toggle" href="#" id="nhookDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                                    Java hook
                                            </a>
                                            <div class="dropdown-menu" aria-labelledby="nhookDropdownMenuLink">
                                                <a class="dropdown-item insertHookSnippet" code="`+codeID+`" hooksnippet="printstacktrace">Print StackTrace</a>
                                                <a class="dropdown-item insertHookSnippet" code="`+codeID+`" hooksnippet="javab2s">String from bytearray</a>
                                                <a class="dropdown-item insertHookSnippet" code="`+codeID+`" hooksnippet="newinstanceof">New instance of</a>
                                                <a class="dropdown-item insertHookSnippet" code="`+codeID+`" hooksnippet="methsignature">Get signature from Method object</a>
                                                
                                            </div>
                                        </li>
                                        <li class="nav-item dropdown">
                                            <a class="nav-link dropdown-toggle" href="#" id="nhookDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                                    Native hook
                                            </a>
                                            <div class="dropdown-menu" aria-labelledby="nhookDropdownMenuLink">
                                                <!-- <a class="dropdown-item insertHookSnippet" code="`+codeID+`" hooksnippet="nhook_fopen">File open</a> -->
                                                <a class="dropdown-item insertHookSnippet" code="`+codeID+`" hooksnippet="nhook_offset">Hook from offset</a>
                                                <!-- <a class="dropdown-item insertHookSnippet" code="`+codeID+`" hooksnippet="nhook_hexdump">Memory hexdump</a> -->
                                            </div>
                                        </li>
                                        <!-- <li class="nav-item">
                                            <a class="nav-link badge badge-pill badge-primar badge-action insertHookSnippet" code="`+codeID+`" hooksnippet="fread" href="#">File read</span>
                                        </li>
                                        <li class="nav-item">
                                            <a class="nav-link badge badge-pill badge-primar badge-action insertHookSnippet" code="`+codeID+`" hooksnippet="breakpoint" href="#">Breakpoint</span>
                                        </li> -->
                                    </ul>
                                <pre id="`+codeID+`">`+htmlEncode(decodeURIComponent(atob(row.script)))+`</pre>
                            </div>
                        </div>
                    </div>
                    <div class="col-lg-4">
                        <div class="card">
                            <div class="card-header">
                                <div class="row">

                                    <div class="col-lg-6 col-md-6" style="font-size:1.2em;" >
                                        Hook messages
                                    </div>
                                    <div class="col-lg-6 col-md-6" style="text-align:right">  
                                        <button class="btn btn-danger replay-hook" code="`+codeID+`" hookid="`+row.id+`" style="font-size:0.8em"><span class="fa fa-refresh">&nbsp;</span>Replay hook</button>
                                    </div>
                                </div>
                            </div>
                            <div class="card-body" style="padding:0px;" id="hook-log-`+row.id+`">
                                <table class="table table-sm-4">
                                        <thead><tr><td><b>Hook data</b></td></tr></thead><tbody><tr><td>Nothing to display</td></tr></tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>`
        //body += '<div class="row"><div class="col-md-offset-10"><button code="'+codeID+'" hookid="'+row.id+'" class="btn btn-primary savechange">Save changes</button></div></div>';
        
        setTimeout(function(){
            saveEditor( codeID, setupAceEditor(codeID));
        },20);

        $(function () {
            $('[data-toggle="tooltip"]').tooltip()
        });

        return body;
    }

   

    $(document).ready(function() {

        DexcaliburAPI.hook.statusServer(
            {
                onSuccess: function(vData){
                    let data = JSON.parse(vData);

                    $("#statusServer").removeClass("badge-success");
                    $("#statusServer").removeClass("badge-danger");

                    if(data.success){
                        $("#statusServer").addClass("badge-success");
                        $("#statusServer").html("running");
                    }else{
                        $("#statusServer").addClass("badge-danger");
                        $("#statusServer").html("stopped (click to start)");
                    }


                }
            }
        );

        $(document).on("click",".showMethod",function(){
            let method = $(this).attr("methid");

            $.ajax('../api/method/'+method,{
                method: 'get',
                statusCode: {
                    200: function(data){
                        renderMethodModal(JSON.parse(data));
                        $('#methodModal').modal();
                    },
                    404: function(){
                        //alert("Failed to update the hook")
                    }
                }
            })
        })
        
        let probeTable = $('#dataTables-probe').DataTable({
            ajax: "../api/probe",
            searching: false,
            paging: false,
            columns: [
                {
                    "className":      'details-control',
                    "orderable":      false,
                    "data":           null,
                    "defaultContent": ''
                },
                {  
                   
                    render: function(data, type, row, meta ){
                        if(row.parentID != null)
                            return (row.color!=null? `<span class="badge badge-pill badge-${row.color}">${row.parentID}</span>`: row.parentID) ;
                        else
                            return '<span class="badge badge-pill badge-primary">custom</span>';                 
                    }
                    //defaultContent: '-'
                },
                { 
                    data: 'name' ,
                    render: function(data, type, row, meta ){
                        return (row.name!=null)? htmlEncode(row.name) : '[Missing]';
                    }
                },
                { 
                    render: function(data, type, row, meta ){
                       // console.log(row);
                     //   let b= '<div class="custom-control custom-switch">'
                      //      +'<input type="checkbox" class="custom-control-input" id="hook-'+btoa(encodeURIComponent(row.name))+'" meth="'+btoa(encodeURIComponent(row.name))+'"/>';
                       //     +'<label class="custom-control-label" for="hook-'+btoa(encodeURIComponent(row.name))+'">On</label>';
                            
                        /*  
                        if(row.enable){
                            b += '<label class="badge badge-pill badge-success custom-control-label" for="hookconfBefore">ON</label>';
                        }else{
                            b += '<label class="badge badge-pill badge-danger custom-control-label" for="hookconfBefore">OFF</label>';
                        }*/
                        //b += '<label class="custom-control-label" for="hookconfBefore">&nbsp;</label>';
                       
//                        return b + '</div>';

                        
                        if(row.enable){
                            return '<span  class="badge badge-pill badge-success probe badge-action" status="true" meth="'+btoa(encodeURIComponent(row.name))+'">ON</span>';
                        }else{
                            return '<span  class="badge badge-pill badge-danger probe badge-action" status="false" meth="'+btoa(encodeURIComponent(row.name))+'">OFF</span>';
                        }
                        /*if(row.edited){
                            return '<a  class="badge badge-pill badge-info">edited</a>';
                        }*/
                    }
                },{
                    render: function(data, type, row, meta ){
                        return '<span style="margin-left:1em;font-size:1.2em;" class="badge badge-pîll badge-action badge-danger probe-del"  hookid="'+row.id+'" data-toggle="tooltip" data-placement="bottom" title="remove"><span class="fa fa-trash"></span></a>';

                        //return '<button style="height:1.5em;padding-top:0px;padding-bottom:0px;" class="btn btn-primary probe-duplicate" hookid="'+row.id+'" data-toggle="tooltip" data-placement="bottom" title="duplicate"><span class="fa fa-copy"></span></button>&nbsp;'
                        //    +'<button style="height:1.5em;padding-top:0px;padding-bottom:0px;" class="btn btn-danger probe-del" hookid="'+row.id+'" data-toggle="tooltip" data-placement="bottom" title="remove"><span class="fa fa-trash"></span></button>';
                    } 
                }
            ],
            responsive: false
        });

        probeTable.on('draw',function(){
            $(function () {
                $('[data-toggle="tooltip"]').tooltip()
            });
        })

        let msgStatus = 0;
        let stopHooks = 1;
        let hookMessages = {
            view: {
                hook_id: null,
                stop_id: null
            }
        };

        $(document).on("click",".replay-hook",function(e){
            msgStatus = 9999999;
            console.log(e);
            hookMessages.view.hook_id = e.target.attributes.hookid.nodeValue;
            //console.log(hookMessages.view.hook_id);
            //hookMessages.view.stop_id = e.target.attributes.code;

            $("#hook-log-"+hookMessages.view.hook_id+" table tbody tr").remove();
            $.ajax('../api/probe/start',{
                method: 'post',
                statusCode: {
                    200: function(){
                        stopHooks = 0;
                        msgStatus = 0;
                        //console.log(e);
                        
                        
                    },
                    404: function(){
                        alert("Failed to start probing(see logs)")
                    }
                }
            })
        });

        $("#dl-fridascript").click(function(){
            location.href = "../api/probe/download";
        });

        
        setInterval(function(){
            if(stopHooks==1) return;

            $.ajax("../api/probe/msg",{
                method: 'get',
                statusCode: {
                    200: function(data,err){
                        var d = JSON.parse(data), msg, color_start, color_end, msgdata, hookMsg;
                        //console.log(d);
                        
                        //probeTable.draw();

                        if(d.data.message.length>msgStatus){


                            //$("#probelogs").html("");

                            for(let i=msgStatus; i<d.data.message.length ; i++){

                                if(atob(d.data.message[i].hook) != hookMessages.view.hook_id) continue;
                                
                                hookMsg = d.data.message[i];
                                msg = hookMsg.msg;

                                msgdata = "";
                                if(hookMsg.data != null){
                                    if(typeof hookMsg.data == "object"){
                                        for(let i in hookMsg.data){
                                            msgdata += htmlEncode(i+" = "+hookMsg.data[i])+"</br>";
                                        }
                                    }else
                                        msgdata = htmlEncode(hookMsg.data);
                                }
                            

                                if(msg != undefined){
                                    $("#hook-log-"+hookMessages.view.hook_id+" table tbody").append(
                                        `<tr>
                                            <td>`+msgdata+`</td>
                                        </tr>`
                                    );
                                    //logTable.row.add(hookMsg);
                                    //logTable.draw();
                                }
                            }
                            msgStatus = d.data.message.length;
                        }
                    },
                    404: function(){
                        //alert("Failed to add probe (see logs)")
                    }
                }
            });
        },100);


        //$('#probelogs').
        $('#dataTables-probe tbody').on('click', 'td.details-control', function () {
            var tr = $(this).closest('tr');
            var row = probeTable.row( tr );
            console.log(row.child.isShown());
            
            if ( row.child.isShown() ) {
                // This row is already open - close it
                row.child.hide();
                tr.removeClass('shown');
            }
            else {
                // Open this row
                row.child( format(row.data()) ).show();
                tr.addClass('shown');
                tr[0].nextElementSibling.childNodes[0].className = 'dxc-expandedrow-bg';
            }
        } );

        let refreshMsgCtr = 0;
        
        $(document).on("click",".probe",function(){
            let DOM_PROBE =$(this);
            let meth = $(this).attr("meth");
            let status = $(this).attr("status");

            status = (status=="true") ? "false" : "true";
            refreshMsgCtr

            $.ajax('../api/probe/'+meth+'?enable='+status,{
                method: 'put',
                statusCode: {
                    200: function(data){
                        console.log(data);
                        DOM_PROBE.attr("status",status);
                        if(status=="true"){
                            DOM_PROBE.removeClass("badge-danger");
                            DOM_PROBE.addClass("badge-success");
                            DOM_PROBE.text("ON").html()
                        }
                        else{
                            DOM_PROBE.removeClass("badge-success");
                            DOM_PROBE.addClass("badge-danger");
                            DOM_PROBE.text("OFF").html()
                        }
                    },
                    404: function(){
                        //alert("Failed to add probe (see logs)")
                    }
                }
            })
        });

        $(document).on("click",".probe-duplicate",function(){
            let DOM_PROBE =$(this);
            let hookid = $(this).attr("meth");
            let status = $(this).attr("status");

            $.ajax('../api/hook/duplicate?id='+hookid,{
                method: 'get',
                statusCode: {
                    200: function(data){
                        alert("Hook duplicate"); 
                    },
                    404: function(){
                        // alert("Failed to update the hook")
                    }
                }
            })
        });
        $(document).on("click",".probe-update",function(){
            let hookid = $(this).attr("hookid");

            $.ajax('../api/hook/'+hookid,{
                method: 'put',
                data: {

                },
                statusCode: {
                    200: function(data){
                        alert("Hook updated"); 
                    },
                    404: function(){
                        //alert("Failed to update the hook")
                    }
                }
            })
        });

        $(document).on("click",".probe",function(){
            let DOM_PROBE =$(this);
            let hookid = $(this).attr("meth");
            let status = $(this).attr("status");

            $.ajax('../api/hook/'+hookid+'?enable='+status,{
                method: 'put',
                statusCode: {
                    200: function(data){
                        //alert("Hook updated");
                    },
                    404: function(){
                        //alert("Failed to update the hook")
                    }
                }
            })
        });

        function buildHookCode(id){
            let code = EditorRegister[id].session.doc;
            let src = [];
            //$lines.map(x=>src.push(encodeURIComponent(x)));
            // return src;
            return code.$lines;
        }

        // save change action
        $(document).on("click","div.savechange",function(){
            var code = buildHookCode($(this).attr("code"));
            var replay = $(this).attr("hookreplay");
            var hookid = $(this).attr("hookid");
            // EditorRegister[$(this).attr("code")].session.doc.$lines.join("\n");
            // console.log(EditorRegister[$(this).attr("code")].session.doc
            $.ajax('../api/hook/'+hookid,{
                method: 'put',
                data: {
                    code: code
                },
                statusCode: {
                    200: function(){
                        if(replay==="auto"){
                            msgStatus = 9999999;
                            //console.log(e);
                            //hookMessages.view.hook_id = e.target.attributes.hookid.nodeValue;
                            hookMessages.view.hook_id = hookid;
                            
                            //console.log(hookMessages.view.hook_id);
                            //hookMessages.view.stop_id = e.target.attributes.code;

                            $("#hook-log-"+hookMessages.view.hook_id+" table tbody tr").remove();
                            $.ajax('../api/probe/start',{
                                method: 'post',
                                statusCode: {
                                    200: function(){
                                        stopHooks = 0;
                                        msgStatus = 0;
                                    },
                                    404: function(){
                                        alert("Failed to start probing(see logs)")
                                    }
                                }
                            })
                        }
                        else
                            alert('Hook updated');
                    },
                    404: function(err){
                        alert('Remote error');
                    }
                }
            });
        });

    
        function getAttr(e,attr){
            for(let i  in e.attributes){
                if(e.attributes[i].name == attr) return e.attributes[i]; 
            }
            return null;
        }

        $(document).on("click",".editHook",function(e){
            let id = getAttr(e,"hookId");
            let codeBlock = e.target.parentElement.nextSibling;
            //console.log(codeBlock);
            codeBlock.firstChild.innerHTML = "<textarea>"+$("<div />").text(codeBlock.innerText).html()+"</textarea>";
            //console.log(id);
        });

        
        $(document).on("click",".probe-del",function(e){
            let id = getAttr(e.target,"hookid");

            console.log("del",id,e.target);
            if(id==null)
                id = getAttr(e.target.parentElement,"hookid")
            
            
            
            
            $.ajax("../api/hook/"+id.value,{
                method: "delete",
                statusCode: {
                    200: function(data){
                        // TODO : Reload the table
                    },
                    404: function(data){
                        alert("An error happens during deletion");
                    }
                }
            });
        });

        // insertHookSnippet
        $(document).on("click",".insertHookSnippet",function(e){
            let id = getAttr(e.target,"hooksnippet").value;
            let code = "";
            let editor = EditorRegister[getAttr(e.target,"code").value];

            console.log("Esditor>",id,editor,editor.getCursorPosition()    );
            switch(id){
                case "printstacktrace":
                    code = `
        DEXC_MODULE.common.printStackTrace()
                    `;
                    break;
                // ajouter is blacklisted

                case "newinstanceof":
                    code = `
        Java.use('<CLASS_FQCN>').$new(<ARGS>);
                    `;
                    break;
                case "methsignature":
                    code = `
        // 'METHOD_OBJ' should be an instance of Method
        // 'METHOD_ARGS_TYPE' should be an array of parameter's classes
        var signature = DEXC_MODULE.reflect.getMethodSignature( 
            Java.cast( METHOD_OBJ.getDeclaringClass(), DEXC_MODULE.common.class.java.lang.Class), 
            METHOD_ARGS_TYPE 
        );
                    `;
                    break;
                case "javab2s":
                    code = `
        Java.use('java.lang.String').$new(Java.array('byte', BYTE_ARRAY_HERE ));
                    `;
                    break;
                case "nhook_symbol":
                    code = `
        Interceptor.attach(
            Module.findBaseAddress( NAME ).add( OFFSET ), {
                onEnter: function(args){
                    send("entering");
                },
                onLeave: function(ret){
                    send("exiting");
                }
        });
                    `;
                    break;
                default:
                    alert("Hook code snippet not supported : "+id);
                    return;
            }
            
            editor.session.insert(
                editor.getCursorPosition(),
                code
            );
        });

        $(".start-hook").click((e)=>{
            let type = e.currentTarget.getAttribute("fridaStartType");
            let config = {};

            if(type == "attach-pid"){
                DexcaliburAPI.device.list(
                    function(pData){
                        let devl = JSON.parse(pData);

                        $("#ps-device-list").empty();
                        $("#ps-device-list").append(`<option disabled selected hidden>Select ...</option>`);
                        for(let i=0; i<devl.data.length; i++){
                            $("#ps-device-list").append(`<option value="${DexcaliburAPI.ui.htmlEncode(devl.data[i].uid)}">${DexcaliburAPI.ui.htmlEncode(devl.data[i].model+' ('+devl.data[i].uid+')')}</option>`)
                        }
                        //console.log(data);

                        $("#attachToModal").modal(); 
                    },
                    function(err){
                        console.log(err);
                    }
                );  
            }else{
                DexcaliburAPI.hook.start(
                    {
                        type: type
                    },
                    function(data){
                        location.href = "/pages/probelog.html#autostart"
                    },
                    function(err){
                        alert(err);
                    }
                );

            }

            console.log(e.currentTarget.getAttribute("fridaStartType"));//.attr("fridaStartType"));
            
        });

       $("#startServer").click(function(vEvent){
            DexcaliburAPI.hook.startServer(
                {  
                    privileged: true,
                    path: null
                },
                {
                    onSuccess: function(vData){
                        let data = JSON.parse(vData);

                        $("#statusServer").removeClass("badge-success");
                        $("#statusServer").removeClass("badge-danger");

                        if(data.success){
                            $("#statusServer").addClass("badge-success");
                            $("#statusServer").html("running");
                        }else{
                            $("#statusServer").addClass("badge-danger");
                            $("#statusServer").html("stopped (click to start)");
                            if(data.msg != null)
                                alert(data.msg);
                        }

                    }
                }
            )
       })

        $("#enable-all").click(()=>{
            DexcaliburAPI.hook.enableAll({
                200: function(daata){
                    
                    probeTable.ajax.reload();
                }
            })
        });

        $("#disable-all").click(()=>{
            DexcaliburAPI.hook.disableAll({
                200: function(data){
                    probeTable.ajax.reload();
                }
            })
        });

        //dmTable.ajax.url("../api/device").load();
        $('#dm-refresh-btn').click(()=>{
            probeTable.ajax.reload();
        });
    });


    </script>

</body>

</html>
